
/**
 * 并发请求
 * @param {string[]} urls 待请求 url 数组
 * @param {Number} maxNum 最大并发数
**/
function concurRequest(urls,maxNum){
	return new Promise((resolve,reject)=>{
		let index = 0;//指向下一次请求的url 对应的下标
		const result = [];//储存所有请求结果
		let count = 0;//当前完成的请求数量
		async function _request(){
			const i = index;
			const url = urls[index];
			index++;
			try{
				const resp = await fetch(url);
				result[i] = resp;
			} catch(err){
				result[i] = err;
			} finally{
				count++;
				if(count == urls.length){
					resolve(result);
					console.log(result,'4444')
				}
				if(index < urls.length){
					_request()
				}
			}
		}
		for(let i = 0; i < maxNum; i++){
			_request()
		}
	})
}

/**
 * 并发任务控制---开始
**/
class SuperTask{
	constructor(parallelCount = 2){
		this.parallelCount = parallelCount;//并发数量
		this.tasks = [];//请求的数组
		this.runningCount = 0;//请求的下标
	}
	add(task){
		return new Promise((resolve,reject)=>{
			this.tasks.push({
				task,
				resolve,
				reject
			});
			this._run()
		})
	}
	_run(){
		while(this.runningCount < this.parallelCount && this.tasks.length){
			const {task,resolve,reject} = this.tasks.shift();
			this.runningCount++;
			Promise.resolve(task()).then(resolve,reject).finally(()=>{
				this.runningCount--;
				this._run()
			})
		}
	}
}

function timeout(time = 1000){
	return new Promise((resolve)=>{
		setTimeout(()=>{
			resolve(time)
		},time)
	})
}

const superTask = new SuperTask()
export function addTask(time,name){
	superTask.add(()=>timeout(time)).then(()=>{
		console.log(`任务${name}完成`)
	})
}

// addTask(1000,1)
// addTask(1000,2)
// addTask(1000,3)
// addTask(1000,4)
// addTask(1000,5)
/**
 * 并发任务控制---结束
**/
export async function testFuns(){//测试点击
	testFuns2()
}

export async function testFuns2(){//测试点击
	return new Promise((resolve,reject)=>{
		let result = [];
		let funs = [];
		let subNum = 0;
		for(let i = 0; i < 5; i++){
			funs.push(()=> newFun(i))
		}
		for(let s = 0; s < funs.length; s++){
			superTask.add(funs[s]).then((res)=>{
				result.push(res)
			}).catch(err=>{
				result.push(err)
			}).finally(()=>{
				subNum++
				if(subNum == funs.length){
					resolve(result)
					console.log(result,'99999')
				}
			})
		}
	})
	
}
function newFun(num){
	return new Promise((resolve,reject)=>{
		setTimeout(()=>{
			if(num == 1){
				reject(`失败${num + 1}`)
			}else{
				resolve(`成功${num + 1}`)
			}
		},2000)
	})
}
export async function testFuns1(){//测试点击
	let funs = []
	for(let i = 0; i < 5; i++){
		funs.push(()=> newFun(i))
	}
	let processor = processTasks(...funs)
	const result = await processor.start()
	console.log(funs,'任务执行完成1111',result)
}
/**
 * 任务队列的中断与恢复
 * 依次顺序执行一系列任务
 * 所有任务全部完成后可以得到每个任务的执行结果
 * 需要返回两个方法，start用于启动任务，pause用于暂停任务
 * 每个任务具有原子性，即不可中断，只能在两个任务之间中断
 * @param {...Function} tasks 任务列表，每个任务无参，异步
**/

export function processTasks(...tasks){
	let isRunning = false
	const result = [];//所有任务的结果
	let i = 0;
	return {
		async start(){
			return new Promise(async (resolve,reject)=>{
				if(isRunning) return
				isRunning = true
				//依次执行任务
				while(i < tasks.length){
					try{
						console.log(`执行第${i+1}个任务！`)
						const r = await tasks[i]();
						result.push(r);
						console.log(`执行第${i+1}完成！`)
					} catch(error){
						result.push(error);
						console.log(`执行第${i+1}失败！`)
					}
					i++;
					if(!isRunning) return;
				}
				isRunning = false;
				resolve(result);
			})
		},
		pause(){
			isRunning = false;
		}
	}
}


